#include "UtilityPCH.h"

#include "UT_GeometryBase.h"
#include "UT_MathHelper.h"

using namespace Utility;

uint32_t UT_GeometryBase::m_suiNextGeometryId = 1;
//--------------------------------------------------------
UT_GeometryBase::UT_GeometryBase()
	: m_pkObjectToWorld(NULL)
	, m_pkWorldToObject(NULL)
	, m_bReverseOrientation(false)
	, m_bTransformSwapsHandedness(false)
	, m_uiGeometryId(m_suiNextGeometryId++)
{
	
}
//--------------------------------------------------------
UT_GeometryBase::UT_GeometryBase(const UT_Transform *o2w, const UT_Transform *w2o, bool bReverseOrientation)
	: m_pkObjectToWorld(o2w)
	, m_pkWorldToObject(w2o)
	, m_bReverseOrientation(bReverseOrientation)
	, m_bTransformSwapsHandedness(o2w->SwapsHandedness())
	, m_uiGeometryId(m_suiNextGeometryId++)
{
		
}
//--------------------------------------------------------
UT_GeometryBase::~UT_GeometryBase()
{

}
//--------------------------------------------------------
UT_BBOX_AABB UT_GeometryBase::GetWorldBound() const
{
	return (*m_pkObjectToWorld)(GetObjectBound());
}
//--------------------------------------------------------
bool UT_GeometryBase::CanIntersect() const
{
	return true;
}
//--------------------------------------------------------
void UT_GeometryBase::Refine(UT_TVector<UT_SmartPointer<UT_GeometryBase>>& rkRefinedVector) const
{	
	GfxWriteLog(LOG_D_DEFAULT_ERROR,"Unimplemented Geometry::Refine() method called");
}
//--------------------------------------------------------
bool UT_GeometryBase::Intersect(const UT_Ray& ray, float* tHit, float* rayEpsilon, UT_DifferentialGeometry* dg) const
{
	GfxWriteLog(LOG_D_DEFAULT_ERROR,"Unimplemented Geometry::Intersect() method called");
	return false;
}
//--------------------------------------------------------
bool UT_GeometryBase::IntersectP(const UT_Ray &ray) const
{
	GfxWriteLog(LOG_D_DEFAULT_ERROR,"Unimplemented Geometry::IntersectP() method called");
	return false;
}
//--------------------------------------------------------
float UT_GeometryBase::Area() const 
{
	GfxWriteLog(LOG_D_DEFAULT_ERROR,"Unimplemented Geometry::Area() method called");
	return 0.;
}
//--------------------------------------------------------
float UT_GeometryBase::Pdf(const UT_Point3Float &p, const UT_Vec3Float &wi) const 
{
	// Intersect sample ray with area light geometry
	UT_DifferentialGeometry dgLight;
	UT_Ray ray(p, wi, 1e-3f);
	ray.depth = -1; // temporary hack to ignore alpha mask
	float thit, rayEpsilon;
	if (!Intersect(ray, &thit, &rayEpsilon, &dgLight)) return 0.;

	// Convert light sample weight to solid angle measure
	float pdf = UT_MathHelper::DistanceSquared(p, ray(thit)) /
		(UT_MathHelper::AbsDot(dgLight.nn, -wi) * Area());
	
	if (isinf(pdf)) pdf = 0.f;
	
	return pdf;
}